from django.template import RequestContext, Context, loader
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.core.paginator import Paginator
from django.utils import simplejson
from django.db.models import Q

from django.contrib.auth.models import User
from online_shop.users.forms import *
from online_shop.products.models import products, categories, sub_categories, inventory_records, product_favourite
from online_shop.orders.models import product_rates, orders, order_details, order_status
from online_shop.users.models import comments, comment_votes, replys
from online_shop.cart.models import CartItem
from online_shop.cart import cart
from online_shop.utils import generate_page_bar

# Create your views here.

# Defalut home page
def main_page(request):
    result = {}
    product_path = '/products'
    categoryitems = categories.objects.all() 
    for cat in categoryitems:
        cat.subitems = sub_categories.objects.filter(category=cat.id)
    # Fetch all recommended products excludes status=1 (1 means not published)
    recommended_productitems = products.objects.filter(recommended=True).exclude(status=1).order_by('-changed')
    # Fetch Top 6 sold products
    hot_productitems = products.objects.all().exclude(status=1).extra(
        tables=["products_inventory_records"],
        where=["products_inventory_records.product_id=products_products.id"],
        order_by=['-products_inventory_records.sales_history']
    )[:6]
    variables = RequestContext(request,{
        'categories': categoryitems,
        'recommeded_products': recommended_productitems,
        'hot_products': hot_productitems,
        'product_path': product_path,
        'recent_viewed': get_recent_viewed_object(request),
        'amount': cart.cart_distinct_item_count(request),
    })
    return render_to_response(
        'main_page.html',
        variables,
    )
    
# Product page
# url: /products/<product_id>/
def product_page(request,product_id=0):
    # get recent viewed before this product be recorded
    recenct_viewed_product = get_recent_viewed_object(request)
    
    #get product info    
    product = get_object_or_404(products,id=product_id,status=0)
    
    # Record product to recented viewed list
    recented_viewed = request.session.get('recent_viewed',[])
    try:
        pos = recented_viewed.index(product_id)
        del(recented_viewed[pos])
        recented_viewed.append(product_id)
    except ValueError:
        recented_viewed.append(product_id)
    if len(recented_viewed)>4:
        del(recented_viewed[0])
    request.session['recent_viewed'] = recented_viewed
    
    #fetch comments
    commentresults = comments.objects.filter(product=product_id).select_related()
    items_per_page = 12
    current_page = 1
    if "page" in request.GET:
        current_page = int(request.GET['page'])
        if current_page<1:
            current_page = 1
    p = Paginator(commentresults, items_per_page)
    if current_page > p.num_pages:
        current_page = p.num_pages
    commentitems = p.page(current_page).object_list;
    page = p.page(current_page)
    page.current_page = current_page
    page.url = "/products/"+product_id+"/?page="
    page.bar = generate_page_bar(p,current_page)
    
    
    try:
        product.rate_img = get_rate_image_type(product.product_rates_value.value)
    except:
        pass
    
    
    #product.rate_img = get_rate_image_type(product.product_rates_value.value)
    variables = RequestContext(request,{
        'amount': cart.cart_distinct_item_count(request),
        'total_price': cart.cart_subtotal(request),
        'product': product,
        'comments': commentitems,
        'page': page,
        'rencent': recented_viewed,
        'recent_viewed': recenct_viewed_product,
    })
    return render_to_response(
        'products/product.html',
        variables,
    )
# Search page
# url: /search/?<paramat>=<value>...
def search_page(request):
    #record search form info
    form = {}
    form['checked_subcategories'] = []
    #get paramas
    for key in request.GET:
        if key == 'searchkeyword' and request.GET['searchkeyword']:
            keyword_value = request.GET['searchkeyword'].encode('utf8')
            form['keyword'] = keyword_value
        elif key == 'category' and request.GET['category']:
            try:
                category_value = request.GET['category'].encode('utf8')
                subcategoryitems = sub_categories.objects.filter(category__name=category_value)
                form['subcategories'] = subcategoryitems
            except:
                category_value = ''
            form['category_value'] = category_value
            
        elif key =='sorted-type' and request.GET['sorted-type']:
            sorted_type = request.GET['sorted-type']
            form['sorted_type'] = sorted_type
        elif key[:11]=='subcategory' and request.GET[key]:            
            form['checked_subcategories'].append(key[11:])    
    
    # start search
    results = products.objects.select_related()
    
    # filter category if it is not All
    if locals().has_key('category_value') and category_value!='':
        results = results.filter(subcategory__category__name=category_value)
        # filter subcategory if it is selected
        if len(form['checked_subcategories'])>0:
            unchecked_subs = sub_categories.objects.filter(category__name=category_value)
            for checked in form['checked_subcategories']:
                unchecked_subs = unchecked_subs.exclude(name=checked)
            for unchecked in unchecked_subs:
                results = results.exclude(subcategory=unchecked.id)        
    
    # filter by keywords
    if locals().has_key('keyword_value'):
        results = results.filter(Q(name__contains=keyword_value) | Q(description__contains=keyword_value))
    # sort the order
    if locals().has_key('sorted_type'):
        if(sorted_type=='pricel2h'):
            results = results.order_by('price')
        elif (sorted_type=='priceh2l'):
            results = results.order_by('-price')
        elif (sorted_type=='rate'):
            results = results.order_by('-product_rates_value__value')
        elif (sorted_type=='sales'):
            results = results.order_by('-inventory_records__sales_history')
    items_per_page = 12
    current_page = 1
    if "page" in request.GET:
        current_page = int(request.GET['page'])
        if current_page<1:
            current_page = 1
    p = Paginator(results, items_per_page)
    if current_page > p.num_pages:
        current_page = p.num_pages
    p_list = p.page(current_page).object_list;
    page = p.page(current_page)
    page.current_page = current_page
    page.url = request.get_full_path().replace("&page=","")+"&page="
    page.bar = generate_page_bar(p,current_page)
    
    for pitem in p_list:
        # generate rate image
        try:
            pitem.rate_img = get_rate_image_type(pitem.product_rates_value.value)
        except:
            pass

    variables = RequestContext(request,{
        'categories' : categories.objects.all(),
        'results': p_list,
        'page': p,
        'searchform': form,
        'recent_viewed': get_recent_viewed_object(request),
        'amount': cart.cart_distinct_item_count(request),
        'page': page,        
    })
    return render_to_response(
        'products/search.html',
        variables,
    )
    
# Ajax return subcategory
# url: /get/subcategory/<category_value>/
def ajax_fetch_subcategory_by_category(request, category_value):
    if int(category_value) !=0:
       subcategoryitems = sub_categories.objects.filter(category__id=category_value)
    else:
        subcategoryitems = sub_categories.objects.filter(category__name=category_value)
    data = {}
    i = 0
    for sub in subcategoryitems:
       data[sub.id] = sub.name 
    return HttpResponse(simplejson.dumps(data),mimetype='application/json')

# products add to cart
# url: products/add_to_cart
def product_to_cart(request):
    result = {}
    if request.method=='POST':
        postdata= request.POST.copy()
        cart.add_to_cart(request)
        product_id = postdata['product-id']
        product = get_object_or_404(products, id=product_id)
        cart_item = get_object_or_404(CartItem, cart_id=cart._cart_id(request), product=product)
        result['cart_id'] = cart_item.id
        result['product_id'] = cart_item.product_id
        result['image'] = str(cart_item.image())
        result['name'] = cart_item.name()
        result['price'] = cart_item.price()
        result['quantity'] = cart_item.quantity
        result['total'] = cart_item.total()
        result['items_amount'] = cart.cart_distinct_item_count(request)
        result['sub_total'] = cart.cart_subtotal(request)
    return HttpResponse(simplejson.dumps(result), mimetype='application/json')
        
# products store up
# url: favourite/<product_id>/
def favourite_product_store_up(request, product_id=0):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/login/')
    user = get_object_or_404(User, username=request.user.username)
    product = get_object_or_404(products, id=product_id)
    result = {}
    favourite_product = product_favourite(
        user_id = user.id,
        product_id = product_id
    )
    favourite_product.save()

    cart_items = cart.get_cart_items(request)
    cart_subtotal = cart.cart_subtotal(request)
    user = get_object_or_404(User, username=request.user.username)
    favourite_products = user.favourite_user.all()
    variables = RequestContext(request,{
        'favourite_products': favourite_products,
        'recent_viewed': get_recent_viewed_object(request),
        'amount': cart.cart_distinct_item_count(request),
        'cart_items': cart_items,
        'cart_subtotal': cart_subtotal,
    })
    return render_to_response(
        'shopping cart/cart_display.html',
        variables,
    )

# favourte product del
# url: favourite/delete/
def favourite_product_del(request):
    result={}
    if request.method == 'POST':
        postdata = request.POST.copy()
        favourite_product = get_object_or_404(product_favourite, id=postdata['favourite_product_id'])
        if favourite_product:
            favourite_product.delete()
            result['success']=True
        else:
            result['success']=False
    return HttpResponse(simplejson.dumps(result), mimetype='application/json')

#add comment_votes
#url: products/comment_votes/
def add_comment_votes(request):
    result = {}
    if request.method=='POST':
        postdata = request.POST.copy()
        order_detail_id = postdata.get('comment_id',0)
        useful_or_not = postdata.get('useful_or_not', -1)
        order_detail = get_object_or_404(order_details, id=order_detail_id)
        comment = get_object_or_404(comments, order_detail=order_detail)
        user = User.objects.get(username=request.user.username)
        comment_vote = comment_votes()
        comment_vote.comment = comment
        comment_vote.user = user
        comment_vote.helpfull_or_not = useful_or_not
        comment_vote.save()
        result['total_num'] = comment.total_num()
        result['useful_num'] = comment.useful_num()
    return HttpResponse(simplejson.dumps(result), mimetype='application/json')

#show commeent reply
#url: products/comment/reply/(\d+)/
def comment_reply(request, order_detail_id):
    order_detail = get_object_or_404(order_details, id=order_detail_id)
    comment = get_object_or_404(comments, order_detail=order_detail)
    if request.method=='POST':
        
        user = User.objects.get(username=request.user.username)
        postdata = request.POST.copy()
        reply_content = postdata.get('reply_content','')
        reply = replys()
        reply.comment = comment
        reply.user = user
        reply.content = reply_content
        reply.save()
    comment_replies = replys.objects.filter(comment=comment)
    variables = RequestContext(request,{
        'product': order_detail.idproduct,
        'replies': comment_replies,
        'comment': comment,
        'recent_viewed': get_recent_viewed_object(request),
        'amount': cart.cart_distinct_item_count(request),
    })
    return render_to_response(
        'products/comment_reply.html',
        variables,
    )
    
#################################################################

# get recent viewed product list
def get_recent_viewed_object(request):
    product_list = []
    recented_viewed = request.session.get('recent_viewed',[])
    recented_viewed.reverse()
    count = 0
    for product_id in recented_viewed:
        try:
            product = products.objects.get(id=product_id, status=0)
            product_list.append(product)
        except:
            del(recented_viewed[count])
            request.session['recent_viewed'] = recented_viewed
    return product_list

def get_rate_image_type(value=0):
    if value <1.5:
        return "1"
    elif value>=1.5 and value <2:
        return "1-5"
    elif value>=2 and value <2.5:
        return "2"
    elif value>=2.5 and value <3:
        return "2-5"
    elif value>=3 and value <3.5:
        return "3"
    elif value>=3.5 and value <4:
        return "3-5"
    elif value>=4 and value <4.5:
        return "4"
    elif value>=4.5 and value <5:
        return "4-5"
    else:
        return "5"